package com.atxwq.shop.manager.serivce.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.atxwq.shop.common.exception.GlobalException;
import com.atxwq.shop.manager.mapper.SysRoleUserMapper;
import com.atxwq.shop.manager.mapper.SysUserMapper;
import com.atxwq.shop.manager.serivce.SysUserService;
import com.atxwq.shop.model.dto.system.AssginRoleDto;
import com.atxwq.shop.model.dto.system.LoginDto;
import com.atxwq.shop.model.dto.system.SysUserDto;
import com.atxwq.shop.model.entity.system.SysUser;
import com.atxwq.shop.model.vo.common.RedisCodeEnum;
import com.atxwq.shop.model.vo.common.ResultCodeEnum;
import com.atxwq.shop.model.vo.system.LoginVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;


import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Description 用户服务实现类
 * @Date 2025/5/7 16:11
 * @Created by 12336
 */

@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleUserMapper sysRoleUserMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public LoginVo login(LoginDto loginDto) {
        //1.获取redis里的验证码和用户输入的验证码
        String captcha = loginDto.getCaptcha();
        String codeKey = loginDto.getCodeKey();

        //2.校验验证码
        String redisCode = redisTemplate.opsForValue().get(RedisCodeEnum.USER_LOGIN_CODE + codeKey);
        if(StrUtil.isEmpty(redisCode) || !StrUtil.equalsIgnoreCase(redisCode , captcha)){
            throw new GlobalException(ResultCodeEnum.VALIDATECODE_ERROR);
        }
        //3.删除redis里的验证码
        redisTemplate.delete(RedisCodeEnum.USER_LOGIN_CODE + codeKey);


        //1.获取提交用户名
        String userName = loginDto.getUserName();
        //2.查询数据库
        SysUser sysUser = sysUserMapper.selectUserInfoByUserName(userName);

        //3.查不到返回错误信息
        if(sysUser == null){
            //throw new RuntimeException("用户名或密码错误");
            throw new GlobalException(ResultCodeEnum.LOGIN_ERROR);
        }

        //4.查到，获取输入密码，比较密码
        String database_Password = sysUser.getPassword();
        String input_Password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        if(!database_Password.equals(input_Password)){
            //throw new Exception("密码错误");
            throw new GlobalException(ResultCodeEnum.LOGIN_ERROR);
        }
        //todo 用jwt生成token令牌
        //5.密码正确，生成token令牌，存到redis中
        String token = UUID.randomUUID().toString().replaceAll("-", "");

        //todo优化redis 1.写入失败的反馈  3.防止穿透问题，
        //将用户信息以生成的 token 为键存入 Redis 中，设置过期时间为 7 天。
        redisTemplate.opsForValue().set(RedisCodeEnum.USER_LOGIN_TOKEN + token, JSON.toJSONString(sysUser),7, TimeUnit.DAYS);

        //6.返回携带token的登录信息loginVo
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        return loginVo;


    }

    /**
     * 根据token 获取用户信息
     * @param token
     * @return
     */
    @Override
    public SysUser getUserInfo(String token) {
        String userInfo = redisTemplate.opsForValue().get(RedisCodeEnum.USER_LOGIN_TOKEN + token);
        //将userInfo转为SysUser对象
        SysUser sysUser = JSON.parseObject(userInfo, SysUser.class);
        return sysUser;
    }

    /**
     * 用户登出
     * @param token
     * @return
     */
    public void logout(String token) {
        redisTemplate.delete(RedisCodeEnum.USER_LOGIN_TOKEN + token);
    }

    /**
     * 分页查询用户信息
     * @param sysUserDto
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<SysUser> findByPage(SysUserDto sysUserDto, Integer pageNum, Integer pageSize) {
        //设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        //查询
        List<SysUser> sysUserList = sysUserMapper.findByPage(sysUserDto);
        //返回
        PageInfo pageInfo = new PageInfo<>(sysUserList);
        return pageInfo;
    }

    /**
     * 添加用户
     * @param sysUser
     */
    @Override
    public void saveSysUser(SysUser sysUser) {
        //1.判断用户名不能重复
        String userName = sysUser.getUserName();
        SysUser dbSysUser = sysUserMapper.selectUserInfoByUserName(userName);
        if(dbSysUser != null){
            throw new GlobalException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        //2.加密处理
        String password = sysUser.getPassword();
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
        sysUser.setPassword(md5Password);

        //3.设置status
        sysUser.setStatus(1);
        sysUserMapper.saveSysUser(sysUser);
    }

    /**
     * 用户修改
     * @param sysUser
     */
    @Override
    public void updateSysUser(SysUser sysUser) {
        sysUserMapper.updateSysUser(sysUser);
    }

    /**
     * 用户删除
     * @param userId
     */
    @Override
    public void deleteById(Long userId) {
        sysUserMapper.deleteSysUserById(userId);
    }

    /**
     * 分配角色权限
     * @param assignRoleDto
     */
    @Override
    public void doAssign(AssginRoleDto assignRoleDto) {
        //1.删除之前分配过的角色权限数据
        sysRoleUserMapper.deleteByUserId(assignRoleDto.getUserId());
        //2.重新分配新的角色权限数据
        List<Long> roleIdList = assignRoleDto.getRoleIdList();
        for (Long roleId : roleIdList) {
            sysRoleUserMapper.doAssign(assignRoleDto.getUserId(), roleId);
        }

    }
}
